﻿using IdentityModel;
using IdentityModel.Client;
using Microsoft.AspNetCore.Authentication;
using Microsoft.AspNetCore.Mvc;
using Microsoft.Extensions.Logging;
using System;
using System.Collections.Generic;
using System.IdentityModel.Tokens.Jwt;
using System.Linq;
using System.Security.Claims;
using System.Threading.Tasks;

namespace PhoneCodeLoginBlzWeb.Controllers
{
    public class AccountController : Controller
    {
        private readonly ILogger _logger;

        public AccountController(ILogger<AccountController> logger)
        {
            _logger = logger;
        }

        /// <summary>
        /// 解析token创建用户clamis，SignIn到当前会话实现登录
        /// </summary>
        /// <param name="tokenResponseJson">Identity Server 4服务器返回包含token的响应</param>
        /// <param name="userInfoJson">用户信息Json</param>
        /// <param name="returnUrl">登录成功后，返回之前的网页路由</param>
        /// <returns></returns>
        [HttpGet]
        public async Task<IActionResult> Login(string tokenResponseJson, string userInfoJson, string returnUrl = "")
        {
            if (string.IsNullOrEmpty(returnUrl))
                returnUrl = "/";

            //TokenResponse属性都是只读的，无法反序列化
            //TokenResponse tokenResponse = System.Text.Json.JsonSerializer.Deserialize<TokenResponse>(tokenResponseJson);
            dynamic tokenResponse = Newtonsoft.Json.JsonConvert.DeserializeObject(tokenResponseJson);
            var jwtSecurityToken = new JwtSecurityToken($"{tokenResponse.AccessToken}");

            var claims = jwtSecurityToken.Claims.ToList();

            dynamic userInfo = Newtonsoft.Json.JsonConvert.DeserializeObject(userInfoJson);

            //提取name
            //claims.Add(new Claim(JwtClaimTypes.Name, $"{userInfo.name}"));
            claims.Add(new Claim(ClaimTypes.Name, $"{userInfo.name}"));

            //提取角色
            //id4返回的角色是字符串数组或者字符串，blazor server的角色是字符串，需要转换，不然无法获取到角色
            var roleElement = userInfo.role;
            if (roleElement is Newtonsoft.Json.Linq.JArray roleAry)
            {
                var roles = roleAry.Select(e => e.ToString());
                //claims.AddRange(roles.Select(r => new Claim(JwtClaimTypes.Role, r)));
                claims.AddRange(roles.Select(r => new Claim(ClaimTypes.Role, r)));
            }
            else
            {
                //claims.Add(new Claim(JwtClaimTypes.Role, roleElement.ToString()));
                claims.Add(new Claim(ClaimTypes.Role, roleElement.ToString()));
            }

            var claimsIdentity = new ClaimsIdentity(claims, "Cookies");
            var claimsPrincipal = new ClaimsPrincipal(claimsIdentity);

            var properties = new AuthenticationProperties
            {
                //记住登录状态
                IsPersistent = true,

                RedirectUri = returnUrl
            };

            await HttpContext.SignInAsync("Cookies", claimsPrincipal, properties);

            _logger.LogInformation($"token登录, returnUrl={returnUrl}");

            return Redirect(returnUrl);
        }

        /// <summary>
        /// 退出登录
        /// </summary>
        /// <returns></returns>
        [HttpGet]
        public async Task<IActionResult> Logout()
        {
            var userName = HttpContext.User.Identity?.Name;

            _logger.LogInformation($"{userName}退出登录。");

            //删除登录状态cookies
            await HttpContext.SignOutAsync("Cookies");

            return Redirect("/");
        }
    }
}
